#include "BulletBehavior.h"




void BulletBehavior::setLeftDirection()
{
	_data->getRect()->Vx = -_BULLET_1_VX * 2;
}

void BulletBehavior::setRightDirection()
{
	_data->getRect()->Vx = _BULLET_1_VX * 2;
}

void BulletBehavior::setUpDirection()
{
	if (_data->getRect()->Vx == 0) {
		_data->getRect()->Vy = 7;
	} else {
		_data->getRect()->Vy = _BULLET_1_VY;
	}
}

void BulletBehavior::setHalfUpDirection()
{
	_data->getRect()->Vy = _BULLET_1_VY;
}

void BulletBehavior::setHalfDownDirection()
{
	if (_data->getRect()->Vx == 0) {
		_data->getRect()->Vy = -7;
	} else {
		_data->getRect()->Vy = -_BULLET_1_VY;
	}
}

void BulletBehavior::setDownDirection()
{
	_data->getRect()->Vy = -_BULLET_1_VY;
}

BulletBehavior::BulletBehavior(BulletData* data)
{
	setBulletData(data);
}

void BulletBehavior::setBulletData(BulletData* data)
{
	_data = data;
	if (_data->type == _ID_BULLET_TANK) {
		_fireStrategy = new BulletFireHalfDownStrategy();
	} else if (_data->type == _ID_BULLET_BOSS_1) {
		_fireStrategy = new BulletFireParapol4Strategy();
	} else if (_data->type == _ID_BULLET_BOSS_1 * 2) {
		_fireStrategy = new BulletFireParapol5Strategy();
	} else if (_data->type == _ID_BULLET_BOSS_1 * 3) {
		_fireStrategy = new BulletFireParapol6Strategy();
	} else if (_data->type == _ID_BULLET_LEVEL_3) {
		_fireStrategy = new BulletFireSinCosStrategy();
	} else {
		_fireStrategy = new BulletFireStraightStategy();
	}
}

void BulletBehavior::setNonTargetDirection()
{
	// Set vx, vy if bullet fired with direction
	// Check fire to the right
	if (_data->direction % _BULLET_DIRECTION_RIGHT == 0) {
		this->setRightDirection();
	}
	else if (_data->direction % _BULLET_DIRECTION_LEFT == 0) {
		this->setLeftDirection();
	}

	// Check fire up or down
	if (_data->direction % _BULLET_DIRECTION_UP == 0) {
		this->setUpDirection();
	}
	else if (_data->direction % _BULLET_DIRECTION_DOWN == 0) {
		this->setDownDirection();
	}
}

void BulletBehavior::setHalfTargetDirection()
{
	double targetX = _data->target->X;
	double targetY = _data->target->Y;

	double bulletX = _data->getRect()->X;
	double bulletY = _data->getRect()->Y;

	double Vy = 0;
	double Vx = -2.3;

	double k  = (targetY - bulletY) / abs(bulletX - targetX);

	if (k > 0.3) {
		if (k > 1) {
			Vy = 3.5;
		} else {
			Vy = 1.4;
		}
	} else {
		Vx = -3;
	}

	_data->getRect()->Vy = Vy;
	_data->getRect()->Vx = Vx;
	_data->getRect()->Y += Vy * 10;
	_data->getRect()->X += Vx * 10;
}

void BulletBehavior::setTargetDirection()
{
	// init data for funtion
	double targetX = _data->target->X;
	double targetY = _data->target->Y;

	double bulletX = _data->getRect()->X;
	double bulletY = _data->getRect()->Y;

	int Vy = 0;
	double Vx = 0;

	double k  = (targetY - bulletY) / abs(bulletX - targetX);
	double absK = abs(k);

	if (absK < 1.5) {
		// Check left or right 
		if (targetX < bulletX - _BULLET_DISTANCE_DELTA) {
			Vx = -1.5;
		}
		else if (targetX > bulletX + _BULLET_DISTANCE_DELTA) {
			Vx = 1.5;
		}
		if (absK > 0.5) {
			Vy = 4 * k;
			Vy = Vy % 2 == 0 ? Vy : Vy + 1;	
		}
	} else {
		Vy = 4 * (k / absK);
	}

	_data->getRect()->Vy = Vy / 2;
	_data->getRect()->Vx = Vy == 0 ? Vx * 1.5 : Vx;
	_data->getRect()->Y += _data->getRect()->Vy * 10;
	_data->getRect()->X += _data->getRect()->Vx * 10;
}

void BulletBehavior::update(long time)
{
	_fireStrategy->update(_data);
}
